package junior.db.dao.update;

import junior.db.dao.base.MybatisHelper;
import org.springframework.util.Assert;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @author wubo
 * @date 2024/8/29 16:11
 */
public class UpsertOption extends SingleInsertOption<UpsertOption> {
    protected String[] updateFields;
    protected Object[] updateValues;
    protected Map<String, Object> updateFieldValueMap;
    protected Map<String, String> updateFieldExpressionMap;
    
    public String[] getUpdateFields() {
        return updateFields;
    }
    
    public Object[] getUpdateValues() {
        return updateValues;
    }
    
    /**
     * 指定要插入的字段
     * @param fields
     * @return
     */
    public UpsertOption withUpdateFields(String... fields) {
        Assert.notEmpty(fields, "Parameter fields is required");
        updateFields = fields;
        return this;
    }
    
    public UpsertOption withUpdateValue(String field, Object value) {
        if (updateFieldValueMap == null) {
            updateFieldValueMap = new HashMap<>();
        }
        updateFieldValueMap.put(field, value);
        return this;
    }
    
    public UpsertOption withUpdateExpression(String field, String expression) {
        if (updateFieldExpressionMap == null) {
            updateFieldExpressionMap = new HashMap<>();
        }
        updateFieldExpressionMap.put(field, expression);
        return this;
    }
    
    @Override
    protected void initFields() {
        super.initFields();
        
        Set<String> fields = new HashSet<>();
        if (updateFields != null) {
            fields.addAll(Arrays.asList(updateFields));
        }
        if (updateFieldValueMap != null) {
            fields.addAll(updateFieldValueMap.keySet());
        }
        if (updateFieldExpressionMap != null) {
            fields.addAll(updateFieldExpressionMap.keySet());
        }
        
        updateFields = fields.toArray(new String[0]);
    }
    
    @Override
    protected void initValues() {
        super.initValues();
        updateValues = new Object[updateFields.length];
        
        for (int i=0; i<updateFields.length; i++) {
            String field = updateFields[i];
            updateValues[i] = getUpdateValue(field);
        }
    }
    
    protected Object getUpdateValue(String field) {
        String expression = updateFieldExpressionMap == null ? null : updateFieldExpressionMap.get(field);
        if (expression != null) {
            return MybatisHelper.sqlToSqlValue(namespace, entityClass, expression, f -> getFieldValue(f));
        }
        return getFieldValue(field);
    }
    
    protected Object getFieldValue(String field) {
        if (ext != null && ext.containsKey(field)) {
            return ext.get(field);
        }
        if (updateFieldValueMap != null && updateFieldValueMap.containsKey(field)) {
            return updateFieldValueMap.get(field);
        }
        return MybatisHelper.getFieldValue(entity, field);
    }
    
}
